<template>
  <div class="vulnerability-container">
    <h2 class="page-title">我的漏洞任务</h2>
    <!-- 加载状态提示 -->
    <el-loading v-if="loading" fullscreen text="正在加载任务数据..." />
    <!-- 错误提示 -->
    <el-alert v-if="errorMsg" type="error" :message="errorMsg" show-icon />
    <!-- 卡片列表容器 -->
    <div class="card-list" v-if="!loading && !errorMsg">
      <!-- 使用v-for循环渲染漏洞任务卡片 -->
      <el-card v-for="task in vulnerabilityTasks" :key="task.taskId" class="task-card">
        <div class="card-header">
          <h3 class="task-title">{{ task.taskName }}</h3>
          <div class="deadline-container">
            <span class="deadline-label">截止时间：</span>
            <span class="deadline" :class="{ expired: isExpired(task.endTime) }">{{ task.endTime }}</span>
          </div>
        </div>
        <div class="card-body">
          <p class="task-desc">{{ task.taskDesc }}</p>
        </div>
        <div class="card-footer">
          <el-tooltip
            :content="isExpired(task.endTime) ? '已经过了结束时间了！' : ''"
            placement="bottom"
            :disabled="!isExpired(task.endTime)"
          >
            <el-button 
              :type="isExpired(task.endTime) ? 'danger' : 'primary'"
              class="eval-button"
              @click="gotoEvaluation(task)"
              :disabled="isExpired(task.endTime)"
            >
              详情下载、及完成提交
            </el-button>
          </el-tooltip>
        </div>
      </el-card>
      <!-- 空状态提示 -->
      <div v-if="vulnerabilityTasks.length === 0" class="empty-state">
        <p>暂无分配的漏洞任务</p>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';
import { useRouter } from 'vue-router';
import { ElCard, ElButton, ElTooltip, ElLoading, ElAlert } from 'element-plus';
// 引入API和store
import myVulnerabilityApi from '@/api/Task/MyVulnerability';
import { userInfo } from '@/stores/userinfo';

// 初始化路由和store实例
const router = useRouter();
const userStore = userInfo();

// 状态管理
const vulnerabilityTasks = ref<Array<any>>([]); // 任务列表数据
const loading = ref<boolean>(true); // 加载状态
const errorMsg = ref<string>(''); // 错误信息

// 定义API响应通用结构接口
// 放在组件内部避免创建单独文件，同时保持类型安全
interface ApiResponse<T> {
  code: number;          // 状态码，0表示成功，非0表示错误
  data: T;               // 响应数据，泛型类型适应不同返回数据结构
  message: string;       // 响应消息，通常用于错误提示
}

// 定义漏洞任务数据结构接口
// 与后端VaTask实体类对应，包含所有必要的任务信息字段
interface VaTask {
  id: number;                 // 任务ID，唯一标识
  title: string;              // 任务标题
  description: string;        // 任务描述
  taskUrl: string;            // 任务文件下载地址
  startTime: string;          // 任务开始时间
  endTime: string;            // 任务结束时间
  createTime: string;         // 任务创建时间
  updateTime: string;         // 任务更新时间
}

/**
 * 判断任务是否已过期
 * @param endTime 截止时间字符串
 * @returns 是否过期
 * 使用严格的时间比较，确保客户端时间与服务器时间一致
 */
const isExpired = (endTime: string) => {
  return new Date(endTime) < new Date();
};

/**
 * 跳转到AI评价页面
 * @param task 任务对象
 * 仅在任务未过期时可调用
 */
const gotoEvaluation = (task: any) => {
  router.push({
    path: '/vatask/AiEvaluation',
    query: {
      taskId: task.taskId,
      taskUrl: task.taskUrl // 传递题目文件下载地址
    }
  });
};

/**
 * 获取用户任务数据
 * 从store获取userId并调用后端接口
 * 处理加载状态和错误情况
 */
const fetchTasks = async () => {
  try {
    loading.value = true;
    errorMsg.value = '';
    
    // 1. 获取用户ID并转换为number类型
    // 从store获取的userId可能是string类型，需要显式转换
    const userIdStr = userStore.userInfo.userId;
    if (!userIdStr) throw new Error('未获取到用户信息');
    
    // 2. 安全地将string转换为number
    // 使用Number()而非parseInt()，因为userId通常是纯数字字符串
    const userId = Number(userIdStr);
    
    // 3. 验证转换结果是否有效
    if (isNaN(userId)) {
      throw new Error('用户ID格式错误,无法转换为数字');
    }

    // 4. 调用API时传入正确的number类型参数
    const response = await myVulnerabilityApi.getTasksByUserId(userId) as ApiResponse<VaTask[]>;

    if (response.code !== 200 || !Array.isArray(response.data)) {
      throw new Error('获取任务数据失败：' + (response.message || '未知错误'));
    }

    vulnerabilityTasks.value = response.data;
  } catch (error: any) {
    errorMsg.value = error.message || '获取任务数据时发生错误';
    console.error('任务数据获取失败:', error);
  } finally {
    loading.value = false;
  }
};


// 组件挂载时获取数据
onMounted(() => {
  fetchTasks();
});

// 监听用户ID变化，重新获取数据
// 处理用户登录状态变化的场景
watch(
  () => userStore.userInfo.userId,
  (newUserId) => {
    if (newUserId) {
      fetchTasks();
    }
  }
);
</script>

<style scoped>
/* 页面容器样式 */
.vulnerability-container {
  padding: 20px;
}

/* 页面标题样式 */
.page-title {
  margin-bottom: 24px;
  color: #333;
  font-size: 20px;
  font-weight: 600;
}

/* 卡片列表布局 */
.card-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
  gap: 20px;
}

/* 任务卡片样式 */
.task-card {
  height: 100%;
  display: flex;
  flex-direction: column;
  transition: box-shadow 0.3s ease;
}

.task-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* 卡片头部样式 */
.card-header {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}

/* 截止时间容器 */
.deadline-container {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* 截止时间标签样式 */
.deadline-label {
  font-size: 12px;
  color: #4b5563;
}

/* 任务名称样式 */
.task-title {
  margin: 0;
  font-size: 18px;
  color: #1f2937;
}

/* 截止时间样式 */
.deadline {
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 4px;
  background-color: #f3f4f6;
  color: #4b5563;
}

/* 过期状态样式 */
.expired {
  background-color: #fee2e2;
  color: #dc2626;
}

/* 卡片内容样式 */
.card-body {
  flex: 1;
  margin-bottom: 16px;
}

/* 任务描述样式 */
.task-desc {
  margin: 0 0 16px 0;
  color: #6b7280;
  line-height: 1.5;
}

/* 卡片底部样式 */
.card-footer {
  display: flex;
  justify-content: flex-end;
  padding-top: 16px;
  border-top: 1px solid #f3f4f6;
}

/* 评价按钮样式 */
.eval-button {
  min-width: 140px;
}

/* 空状态样式 */
.empty-state {
  grid-column: 1 / -1; /* 跨所有列 */
  text-align: center;
  padding: 40px 0;
  color: #9ca3af;
  background-color: #f9fafb;
  border-radius: 8px;
}
</style>